iT邦幫忙

2024 iThome 鐵人賽

DAY 4
0

Feature envy

簡介

當有個方法,他處理眾多的欄位、函數來自於別的class, 這方法稱之為feature envy.

重構前範例

假設有位富人, 聘請一位僕人做家事, 準備邀請客人來家裡.
此時會有這兩個class:

public class Servant
{
    private bool _isFloorSwept = false;
    private bool _areDishesWashed = false;
    private bool _isLaundryDone = false;
    public void SweepFloor()
    {
        _isFloorSwept = true;
    }

    public void WashDishes()
    {
        _areDishesWashed = true;
    }

    public void DoLaundry()
    {
        _isLaundryDone = true;
    }

    public bool AreChoresDone()
    {
        return _isFloorSwept && _areDishesWashed;
    }
}

public class Master
{
    private Servant _servant;
    public Master(Servant servant)
    {
        _servant = servant;
    }

    public void SweepFloor()
    {
        _servant.SweepFloor();
    }

    public void WashDishes()
    {
        _servant.WashDishes();
    }

    public void DoLaundry()
    {
        _servant.DoLaundry();
    }


    public bool AreChoresDone()
    {
        return _servant.AreChoresDone();
    }

    public bool IsReadyToInviteCustomer()
    {
        return AreChoresDone();
    }
}

重構後範例

發現到, 主人的4種函數SweepFloor(), WashDishes(), DoLaundry(), AreChoresDone(), 都是僕人該做的.
因此, 我們可以將這4種函數從主人類別移除, 並修改IsReadyToInviteCustomer().

public class Master
{
    private Servant _servant;
    public Master(Servant servant)
    {
        _servant = servant;
    }

    public bool IsReadyToInviteCustomer()
    {
        return _servant.AreChoresDone();
    }
}

經過這種重構, 使主人類別不再有僕人的功能, 保持主人與僕人各自的職責.

重構補充說明

如果feature envy不處理, 容易導致高耦合的物件群. 日後要重構的時候, 得花時間做分離.
二來做測試時也很麻煩, 以重構前的Master為例, 得Mock Servant的各種行為才能測試完成.


上一篇
Data clump的重構
下一篇
Replace Nested Conditional with Guard Clauses 的重構
系列文
程式淨化計畫:痛苦是重構的起源!31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言